<template>
  <div class="container">
    <div>选择的文件:{{ fileMsg || '未选择' }} {{ fileSize || '' }}{{ }}</div>
    <div class="file-upload-fragment">
      <div class="file-upload-fragment-container">
        <el-upload
          class="fufc-upload"
          action
          :on-change="handleFileChange"
          :auto-upload="false"
          :show-file-list="false"
        >
          <template #trigger>
            <el-button class="fufc-upload-file" size="small" type="primary">选择文件</el-button>
          </template>
          <el-button
            class="fufc-upload-server"
            size="small"
            type="success"
            @click="handleUploadFile"
          >上传到服务器</el-button>
          <el-button class="fufc-upload-stop" size="small" type="primary" @click="stopUpload">暂停上传</el-button>
          <el-button
            class="fufc-upload-continue"
            size="small"
            type="success"
            @click="continueUpload"
          >继续上传</el-button>
        </el-upload>
        {{ percentage || '22222' }}
        <el-progress :percentage="percentage" color="#409eff" />
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { createMD5 } from './utils/md5'
import { postFile, mergeFile } from './api/upload'
import { ElMessage } from 'element-plus'
// let percentage = ref(0)
let fileMsg = ref('')
let fileSize = ref('')
let currentFile = ref(null)
let fileHash = ref(null)
let chunkFormData = ref([])

let percentage = computed(() => {
  if (!chunkFormData.value.length) return 0
  let uploaded = chunkFormData.value.filter((item) => item.percentage).length
  console.log('comming', uploaded, Number(((uploaded / chunkFormData.value.length) * 100).toFixed(2)))
  return Number(((uploaded / chunkFormData.value.length) * 100).toFixed(2))
})
/**
 * @description: 分片上传回调
 * @param {*}
 * @return {*}
 */
const uploadProgress = (item) => {
  // 返回一个 函数  这个函数会在上传进度更改时触发
  return (e) => {
    console.log('progress', e.loaded, e.total)
    item.percentage = parseInt(String((e.loaded / e.total) * 100))
  }
}


const chunkSize = 5 * 1024 * 1024 // 每个文件分片的大小是5M
/**
 * @description: 文件上传 Change 事件
 * @param {*}
 * @return {*}
 */
const handleFileChange = async (file) => {
  fileMsg.value = file.name
  fileSize.value = (file.size / 1000) + 'k'
  if (!file) return
  currentFile.value = file
  console.log('currentFile', file)
}
/**
 * @description: 文件上传 Click 事件
 * @param {*}
 * @return {*}
 */
const handleUploadFile = async () => {
  // 上传文件
  // 文件分片
  let fileList = createChunkList(currentFile.value.raw, chunkSize)
  fileHash.value = await createMD5(fileList)

  let chunkList = fileList.map((file, index) => {
    return {
      file: file,
      chunkHash: fileHash.value + '-' + index, // chunk哈希
      fileHash: fileHash.value, // 文件哈希
    }
  })

  chunkFormData.value = chunkList.map(chunk => {
    let formData = new FormData()
    formData.append('chunk', chunk.file)
    formData.append('chunkHash', chunk.chunkHash)
    formData.append('fileHash', chunk.fileHash)
    return { formData }
  })

  Promise.all(chunkFormData.value.map(data => {
    return new Promise((resolve, reject) => {
      postFile(data.formData, uploadProgress(data)).then(res => {
        resolve(res)
      }).catch(err => {
        reject(err)
      })
    })
  })).then(res => {
    // 所有的分片都上传完成之后  调用合并文件接口 传递文件名 文件哈希 chunk大小
    mergeFile({
      fileName: currentFile.value.name,
      fileHash: fileHash.value,
      chunkSize: chunkSize
    }).then(res => {
      ConstantSourceNode.log(res)
    })
  })

  console.log('fileList', fileList)
}
/**
 * @description: 暂停上传 Click 事件
 * @param {*}
 * @return {*}
 */
const stopUpload = () => {
}
/**
 * @description: 继续上传 Click 事件
 * @param {*}
 * @return {*}
 */
const continueUpload = async () => {
  let res = await mergeFile({ filename: 'hello', fileHash: 'sss', chunkSize: 3 })
}


/**
 * 文件切片
 */
const createChunkList = (file, chunkSize) => {
  const fileChunkList = []
  let cur = 0
  while (cur < file.size) {
    // file 是Blob二进制对象 可以使用 file.slice 实现文件的切片上传 
    fileChunkList.push(file.slice(cur, cur + chunkSize))
    cur += chunkSize
  }
  return fileChunkList
}
</script>

<style scoped >
.container {
  width: 100vw;
  /* height: 100vh; */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding-top: 400px;
}
.file-upload-fragment {
  width: 100%;
  height: 100%;
  padding: 10px;
  /* margin-top: 400px; */
  overflow: hidden;
}
.file-upload-fragment-container {
  position: relative;
  margin: 0 auto;
  width: 600px;
  height: 300px;
  top: calc(50% - 150px);
  min-width: 400px;
}
.fufc-upload {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.el-progress {
  margin-top: 10px;
}
.el-progress::v-deep(.el-progress__text) {
  min-width: 0px;
}
</style>
